package br.ufpe.cin.imlm2.jbeat.soot.common;

import java.util.Map;
import java.util.Map.Entry;

import soot.PhaseOptions;
import soot.Scene;
import soot.jimple.paddle.PaddleHook;
import soot.jimple.spark.SparkTransformer;
import soot.jimple.toolkits.callgraph.CHATransformer;
import soot.jimple.toolkits.callgraph.CallGraph;

import br.ufpe.cin.imlm2.util.Options;

public class JBeatOptions extends Options {

	public static final String CALLGRAPH = "callgraph";
	protected CallGraph callgraph = Scene.v().getCallGraph();
	private static String CURRENT_CG = "cha";

	public static final String STD_LIBRARIES = "std_libraries";
	protected boolean __std_libraries = true;

	public static final String STATIC_INITIALIZERS = "static_initializers";
	protected boolean __static_initializers = false;

	public static final String SYNTHETIC_ENTITIES = "synthetic_entities";
	protected boolean __synthetic_entities = false;

	public static final String ENABLED = "enabled";
	protected boolean __enabled = true;

	public static final String VERBOSE = "verbose";
	protected boolean __verbose = false;

	public JBeatOptions(Map<String, String> options) {
		super();
		this.parse(options);
	}

	@Override
	protected void parse(Map<String, String> options) {
		try {
			super.parse(options);
		} catch (NoSuchOptionException e) {
			System.err.println("Ignoring unkwon JBeat option: "
					+ e.getInvalidOtion());
		}
		for (Entry<String, String> entry : options.entrySet()) {
			if ((entry.getKey().equalsIgnoreCase(CALLGRAPH))) {
				this.switchCG(entry.getValue());
				this.callgraph = Scene.v().getCallGraph();
			}
		}
	}

	private void switchCG(String value) {
		if (value.equalsIgnoreCase(JBeatOptions.CURRENT_CG))
			return;

		if (value.equalsIgnoreCase("cha")) {
			CHATransformer.v().transform("cg.cha",
					PhaseOptions.v().getPhaseOptions("cg.cha"));
		} else if (value.equalsIgnoreCase("spark")) {
			SparkTransformer.v().transform("cg.spark",
					PhaseOptions.v().getPhaseOptions("cg.spark"));
		} else if (value.equalsIgnoreCase("paddle")) {
			PaddleHook.v().transform("cg.paddle",
					PhaseOptions.v().getPhaseOptions("cg.paddle"));
		}
	}

	public CallGraph getCallgraph() {
		return this.callgraph;
	}

	public boolean isRt_libraries() {
		return this.__std_libraries;
	}

	public boolean isStatic_initializers() {
		return this.__static_initializers;
	}

	public boolean isSynthetic_entities() {
		return this.__synthetic_entities;
	}

	public boolean isVerbose() {
		return this.__verbose;
	}

	public boolean isEnabled() {
		return this.__enabled;
	}

}
